from unittest import result
import pandas as pd
import re

start_col = 4
start_row = 5

# 全局变量，存储课程信息
# 课程信息的格式为：
# {
#     "网络4"：{
#        "Linux操作系统" : {
#            "理论": [],
#            "实验": []
#        },
#        "网络虚拟化" : {
#            "理论": [],
#            "实验": []
#        }
#    }
# }
g_course_info = {}


def read_course_schedule(file_path):
    """
    读取课表文件
    :param file_path: 课表文件的路径
    :return: 读取到的课表数据
    """
    try:
        # 假设课表文件是 Excel 文件，使用 pandas 读取
        data = pd.read_excel(file_path, header=None)
        # 从第start_row行开始读取
        data = data.iloc[start_row:]
        # 从第start_col列开始读取
        data = data.iloc[:, start_col:]

        # 输出data到文件
        #data.to_csv("course_schedule.csv", index=False, header=False)
        return data
    except FileNotFoundError:
        print(f"错误：文件 {file_path} 未找到。")
        return None
    except Exception as e:
        print(f"读取文件时发生错误：{e}")
        return None


def get_week_info(week_info):
    """
    解析周数信息
    :param week_info: 周数信息字符串
    :return: 解析后的周数列表
    """

    result = []

    # 先处理中文中括号
    week_info = week_info.replace("【", "").replace("】", "")
    week_info = week_info.split("周")[0]
    # 再处理逗号，这个时候就已经是列表了
    week_infolist = week_info.split(",")

    for week_info in week_infolist:
        week_info = week_info.strip()

        week_info = week_info.split("-")
    
        # 如果week_info[1] 中包含‘(单)’，则只返回单周的列表
        # 如果week_info[1] 中包含‘(双)’，则只返回双周的列表
        # 否则，返回所有周数的列表
        if len(week_info) == 1:
            result.append(int(week_info[0]))
        elif "(单)" in week_info[1]:
            week_info[1] = week_info[1].replace("(单)", "")
            result.extend(list(range(int(week_info[0]), int(week_info[1])+1, 2)))
        elif "(双)" in week_info[1]:
            week_info[1] = week_info[1].replace("(双)", "")
            result.extend(list(range(int(week_info[0]), int(week_info[1])+1, 2)))
        else:
            result.extend(list(range(int(week_info[0]), int(week_info[1])+1)))

    return result



# 解析每一个单元格的课程信息
def parse_course_info(cell_value, row_index, col_index):
    """
    解析单元格中的课程信息
    :param cell_value: 单元格中的值
    :return: 解析后的课程信息
    """
    if pd.isna(cell_value):
        return None
    
    # 如果一个单元格有多门课，会使用"------------"分隔
    parts = cell_value.split("………………")
    for course in parts:
        course = course.strip()
        '''
        每个课程信息有4行，分别是：
        ·
        网络虚拟化技术应用
        【6周】
        主教学楼阶6
        网络虚拟化技术应用(专业核心课)-理论00224网络2
        (49|48)
        ·
        第一行是课程名称
        第二行是周数
        第三行是教学楼
        第四行班级人数
        '''

        # 解析课程信息
        course_name = course.split("\n")[0].strip()
        week_info = course.split("\n")[1].strip()
        # 上课类型/班级信息
        class_type_info = course.split("\n")[3].strip().split('-')[1]
        # class_type_info 包含3部分，可依据第二部分（一个5位数字）进行拆分。后续可使用正则表达式匹配该5位数字以实现拆分。
        match = re.match(r"([理论实验]+)(\d{5})(.+)", class_type_info)
        if match:
            course_type = match.group(1)  # 第一部分：课程类型（如"理论"）
            five_digit_number = match.group(2)  # 第二部分：5位数字
            class_name = match.group(3)  # 第三部分：班级名称
            
            # 输出解析结果
            # print(f"课程名称: {course_name}")
            # print(f"周数信息: {week_info}")
            # print(f"课程类型: {course_type}")
            # print(f"班级名称: {class_name}")

            # 通过 week_info 构建周数信息
            weeklist = get_week_info(week_info)
            for week in weeklist:
                number = f"{week}{col_index+1}0{row_index+1}0{row_index+2}"
                
                # 存储课程信息, 只存储编号, class_name 班级名，如"网络4"
                if class_name not in g_course_info:
                    g_course_info[class_name] = {}
                if course_name not in  g_course_info[class_name]:
                    g_course_info[class_name][course_name] = {}
                if course_type not in g_course_info[class_name][course_name]:
                    g_course_info[class_name][course_name][course_type] = []
                g_course_info[class_name][course_name][course_type].append(number)

        else:
            print(f"未能成功解析class_type_info: {class_type_info}")
    

# 解析data
def parse_course_schedule(data):
    """
    解析课表数据
    :param data: 读取到的课表数据
    :return: 解析后的课表数据
    """
    if data is None:
        return None
    
    # 第1列是节次，第2-8列都是具体的课程信息
    # 把data转为列表
    data_list = data.values.tolist()
    # 遍历列表，解析课程信息, 这个循环表示按行遍历
    for row_num in range(len(data_list)):
        # 只解析偶数行（即0,2,4,6,8）
        if row_num % 2 != 0:
            continue
        row = data_list[row_num]
        # 这个循环表示，遍历这一行的每个单元格
        for col_num in range(len(row)):
            if pd.notna(row[col_num]):
                parse_course_info(row[col_num], row_num, col_num)
    

def print_course_info():
    for class_name in g_course_info:
        for course_name in g_course_info[class_name]:
            for course_type in g_course_info[class_name][course_name]:
                print(f"{class_name} {course_name} {course_type}，共{len(g_course_info[class_name][course_name][course_type])}节: {sorted([int(x) for x in g_course_info[class_name][course_name][course_type]])}")

    # 输出到文件，每个班一个文件，每个编号占一行
    for class_name in g_course_info:
        for course_name in g_course_info[class_name]:
            for course_type in g_course_info[class_name][course_name]:
                with open(f"{class_name}_{course_name}_{course_type}.txt", "w") as f:
                    for number in sorted([int(x) for x in g_course_info[class_name][course_name][course_type]]):
                        f.write(f"{number}\n")



if __name__ == "__main__":
    # 假设课表文件名为 "course_schedule.xlsx"，放在当前目录下
    file_path = "course_schedule.xlsx"
    course_data = read_course_schedule(file_path)

    parse_course_schedule(course_data)

    print_course_info()
